package framework.cglib;

import com.me.common.pojo.Student;
import net.sf.cglib.beans.BeanMap;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * Cglib BeanMap 测试：bean 与 map 互相转换（注意：属性的首字母大写在 map 中会变成小写）
 *
 * @author ME
 * @date 2021/1/18
 */
public class TestBeanMap {

    private Student student;

    @Test
    public void testBean2Map() {
        BeanMap beanMap = BeanMap.create(student);
        System.out.println("\nBean => Map");
        System.out.println(beanMap);

        beanMap.setBean(new Student("Tom", 13, LocalDate.of(1992, 6, 18)));
        System.out.println(beanMap);

        // 用 Map<String, String> 接收 BeanMap.create() 也不会报错
        Map<String, String> map = BeanMap.create(student);
        System.out.println(map);
    }

    @Test
    public void testBean2Map2() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        System.out.println("\nApache BeanUtils");
        Map<String, String> beanMap = org.apache.commons.beanutils.BeanUtils.describe(student);
        beanMap.remove("class");
        System.out.println(beanMap);
    }

    @Test
    public void testBean2Map3() {
        System.out.println("\n使用 Spring BeanUtils 对象转map");
        Map<String, Object> beanMap = Arrays.stream(BeanUtils.getPropertyDescriptors(student.getClass())).filter(item -> !"class".equals(item.getName()))
                .collect(HashMap::new, (map, pd) -> map.put(pd.getName(), ReflectionUtils.invokeMethod(pd.getReadMethod(), student)),
                        HashMap::putAll);
        System.out.println(beanMap);
    }

    @Test
    public void testMap2Bean() {
        Student student = new Student();
        BeanMap beanMap = BeanMap.create(student);

        System.out.println("\nMap => Bean");
        Map<String, Object> map = new HashMap<>(4);
        map.put("name", "Lucy");
        map.put("age", 13);
        map.put("birthday", LocalDate.now());
        beanMap.putAll(map);
        System.out.println(student);
    }

    @Before
    public void before() {
        student = new Student("ljy", 15, LocalDate.now());
    }

}
